<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>

</body>

<!--闭包资源（变量）共用------------------------------------------------------------>
<script type="text/html">
    //
    var ress, res1, res2, res3;

    function a() {
    var x = 0;
    var y = 100;
    var z = "";

    function b() {
    y--;
    z += "*";
    return ++x;
    }

    function c() {
    return --y;
    }

    function d() {
    return z += "*";
    }

    return [b, c, d];
    }

    ress = a();
    res1 = ress[0];
    res2 = ress[1];
    res3 = ress[2];
    ress[2] = function () {
    };
    console.log(res1());
    console.log(res1());
    console.log(res1());
    console.log(res1());
    console.log(res2());
    console.log(res2());
    console.log(res3());
    //置空
    // res1 = a()[0];
    // res2 = a()[1];
    ress = a();
    res1 = ress[0];
    res2 = ress[1];
    console.log(res1());
    console.log(res1());
    console.log(res2());
    console.log(res2());
    console.log(res3());
</script>

<!--闭包彼此独立------------------------------------------------------------------->
<script type="text/html">
    //
    function clo() {
    var num = 0;

    function a() {
    return ++num;
    }

    function b() {
    return --num;
    }

    return [a, b];
    }

    var arr = clo();
    console.log(arr[0]());
    console.log(arr[0]());
    console.log(arr[0]());
    console.log(arr[1]());
    var a1 = clo()[0];
    console.log(a1());
    console.log(a1());
    console.log(a1());
    console.log(a1());
    console.log(arr[0]());
    console.log(arr[0]());
    console.log(arr[0]());
</script>

<!--变量的链式寻找----------------------------------------------------------------->
<script type="text/html">
    //
    var i = 5;                              //全局空间的i
    function test() {
    var x = 0;
    var arr = [];
    // var i;                              //这一句说明了，未声明变量会到其父空间去找，找到全局空间还找不到，就定义给全局空间
    // for (; i < 10; i++) {               //这个i由于并没有在test空间中对其定义，因此是属于全局空间的，对其所作的更改会保存在全局空间里
    for (var i = 0; i < 10; i++) {      //这个i是被定义在test执行空间的，对其所作的更改会保存在test执行空间里
    arr[i] = function () {
    document.write(i + " ");
    // document.write(++x + " ");  //闭包操作私有变量的正确用法
    }
    }
    // document.write(i + " === ");        //这一句说明了变量的存在是以函数执行空间为单位的，且可以重复声明
    return arr;
    }

    var myArr = test();                     //test执行完后，由于返回函数，所以其执行空间形成闭包并保留
    for (var j = 0; j < 10; j++) {
    myArr[j]();                         //这些函数都会访问其闭包中的变量i（已经被计算为10了）
    }
    document.write("=== " + i);             //test中定义了i的话，其更改不会保存在全局空间，否则相反
</script>

<!--用立即执行函数固定变量---------------------------------------------------------->
<script type="text/html">
    //
    function test() {
    var x = 60;
    var arr = [];
    for (var i = 0; i < 10; i++) {
    (function (j) {
    arr[i] = function () {
    console.log(j + " - " + x++);
    }
    }(i));
    }
    return arr;
    }

    var myArr = test();
    for (var j = 0; j < 10; j++) {
    myArr[j]();
    }
    console.log('----------');
    for (var j = 0; j < 10; j++) {
    myArr[j]();
    }
    console.log('----------');
    for (var j = 0; j < 10; j++) {
    myArr[j]();
    }
    console.log('----------');
    var myArr = test();
    for (var j = 0; j < 10; j++) {
    myArr[j]();
    }
</script>

<!--用中间层函数固定变量------------------------------------------------------------>
<script type="text/html">
    //
    function test() {
    var arr = [];
    var a = 0;
    for (var i = 0; i < 10; i++) {
    function x(i) {
    arr[i] = function () {
    console.log(i * i + ' - ' + a++);
    }
    }

    x(i);
    }
    return arr;
    }

    var myArr = test();
    for (var j = 0; j < 10; j++) {
    myArr[j]();
    }
    for (j = 0; j < 10; j++) {
    myArr[j]();
    }
    console.log('---------------');
    myArr = test();
    for (j = 0; j < 10; j++) {
    myArr[j]();
    }
</script>
<script>
    // type="text/html"
    function some(num) {
        num = num ? num : 0;
        return function (x) {
            console.log(num += (x ? x : 1));
        }
    }

    var s1 = some(1);
    var s2 = some(10);
    s1(2);
    s2(3);
    s1(4);
    s1();
    s2();
    var s3 = some();
    s3();
    s3(5);
    s3('a');
    console.log('------------');
    var s4 = some('');
    s4();
    s4('');
</script>
</html>